package com.ys.web.ws.send.schedule;

import com.ys.base.BaseConstants;
import com.ys.base.EnumType;
import com.ys.utils.base.j2se.DateHandler;
import com.ys.utils.base.j2se.JsonUtil;
import com.ys.utils.base.j2se.Logger;
import com.ys.utils.base.j2se.StringHandler;
import com.ys.utils.redis.Redis;
import com.ys.utils.redis.key.UserKey;
import com.ys.utils.spring.properties.Config;
import com.ys.web.user.friends.mapper.UserGroupMapper;
import com.ys.web.user.friends.mapper.UserWxMapper;
import com.ys.web.user.friends.po.BaseUserWxPO;
import com.ys.web.ws.bean.MessageResponseBean;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ 名称:
 * @ 创建人: dhf
 * @ 参数： null
 * @ 创建时间: 2022/5/11
 * @ 修改人和其它信息
 * @ 返回值:
 */
@Component
@Slf4j
public class MessageGroupClearSchedule implements Job {

    @Autowired
    private UserWxMapper userWxMapper;

    @Autowired
    private UserGroupMapper userGroupMapper;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {

        Map<Object, Object> all = Redis.hash.hgetall(UserKey.connectTimeKey());
        Long start_time = System.currentTimeMillis() / 1000;
        int endDate = StringHandler.getInt(DateHandler.getDateString(new Date(), "yyyyMMdd"));

        List<BaseUserWxPO> baseUserWxPOS = userWxMapper.selectAll();
        //查询所有的群主和管理员的id
        List<String> baseUserGroupPOS = userGroupMapper.findAllManager();

        if (!baseUserWxPOS.isEmpty()) {
            if (!all.isEmpty()) {
                //用户保留当前时间
                int time = StringHandler.getInt(Config.pp.getOrDefault("user.read.clear.time", "6"));
                int time2 = StringHandler.getInt(Config.pp.getOrDefault("user.read.clear.time2", "1"));
                LocalDateTime now = LocalDateTime.now();
//                LocalDateTime compareTime = now.plusHours(-time);
                DateTimeFormatter dtf = DateTimeFormatter.ofPattern(BaseConstants.BASE_FORMAT);
                baseUserWxPOS.forEach(obj -> {
                    LocalDateTime compareTime = null;
                    if (baseUserGroupPOS.contains(obj.getId())) {
                        compareTime = now.plusHours(-time);
                    } else {
                        compareTime = now.plusHours(-time2);
                    }
                    String key = UserKey.userUnReadMessageEntityKey(obj.getId());
                    String noticeKey = UserKey.noticeKey(obj.getId());
                    Object o = all.get(obj.getId());
                    if (StringHandler.isNotEmpty(o) && (DateHandler.getDaySub(StringHandler.getInt(o), endDate) < 2)) {
                        this.delGroupEntityByTime(key, compareTime, dtf);
                        this.delNoticeByTime(noticeKey, compareTime, dtf);
                    } else {
                        this.delGroupEntity(key);
                        this.delNotice(noticeKey);
                    }
                });
            }

        }

        Long end_time = System.currentTimeMillis() / 1000;
        Logger.info("Redis数据清理完成，当前耗时：" + (end_time - start_time) + "秒");
    }

    /**
     * 删除用户超过指定时间的数据
     *
     * @param key
     * @param compareTime
     * @param dtf
     */
    private void delGroupEntityByTime(String key, LocalDateTime compareTime, DateTimeFormatter dtf) {
        Map<Object, Object> map = Redis.hash.hgetall(key);
        Map<String, String> newMap = new HashMap<>();
        map.forEach((k, v) -> {
            MessageResponseBean messageResponseBean = JsonUtil.jsonToBean((String) v, MessageResponseBean.class);
            if (StringHandler.isNotEmpty(messageResponseBean.getGroupId())) {
                if (StringHandler.isNotEmpty(messageResponseBean.getCreateTime())) {
                    try {
                        LocalDateTime time = LocalDateTime.parse(messageResponseBean.getCreateTime(), dtf);
                        if (compareTime.isBefore(time)) {
                            newMap.put(messageResponseBean.getMessageId(), v.toString());
                        }
                    } catch (Exception e) {
                        log.error("MessageGroupClearSchedule---删除群未读消息错误",v,e);
                        newMap.put(messageResponseBean.getMessageId(), v.toString());
                    }
                }
            } else {
                newMap.put(messageResponseBean.getMessageId(), v.toString());
            }
        });
        Redis.key.del(key);
        Redis.hash.hmset(key, newMap);
    }

    private void delNoticeByTime(String key, LocalDateTime compareTime, DateTimeFormatter dtf) {
        List<String> range = Redis.list.range(key, 0L, -1L);
        List<String> pushList = new ArrayList<>();
        if (!range.isEmpty()) {
            range.forEach(x -> {
                MessageResponseBean messageResponseBean = JsonUtil.jsonToBean(x, MessageResponseBean.class);
                if (StringHandler.isNotEmpty(messageResponseBean.getGroupId())) {
                    if (StringHandler.isNotEmpty(messageResponseBean.getCreateTime())) {
                        try {
                            LocalDateTime time = LocalDateTime.parse(messageResponseBean.getCreateTime(), dtf);
                            if (compareTime.isBefore(time)) {
                                pushList.add(x);
                            }
                        } catch (Exception e) {
                            log.error("MessageGroupClearSchedule---删除群未读通知错误",x,e);
                            pushList.add(x);
                        }
                    }
                } else {
                    pushList.add(x);
                }
            });
            Redis.key.del(key);
            if (!pushList.isEmpty()) {
                Redis.list.pushList(key, pushList);
            }
        }
    }

    /**
     * 删除所有群消息
     *
     * @param key
     */
    private void delGroupEntity(String key) {
        Map<Object, Object> map = Redis.hash.hgetall(key);
        Map<String, String> newMap = new HashMap<>();
        map.forEach((k, v) -> {
            MessageResponseBean messageResponseBean = JsonUtil.jsonToBean((String) v, MessageResponseBean.class);
            if (StringHandler.isEmpty(messageResponseBean.getGroupId())) {
                newMap.put(messageResponseBean.getMessageId(), v.toString());
            }
        });
        Redis.key.del(key);
        Redis.hash.hmset(key, newMap);
    }

    //0 0 0/1 * * ?
    private void delNotice(String key) {
        List<String> range = Redis.list.range(key, 0L, -1L);
        if (!range.isEmpty()) {
            List<String> collect = range.stream()
                    .map(x -> JsonUtil.jsonToBean(x, MessageResponseBean.class))
                    .filter(x -> StringHandler.isEmpty(x.getGroupId()) && x.getCode() != EnumType.MessageCode.SYS_NOTICE.getCode().intValue())
                    .map(JsonUtil::toJson).collect(Collectors.toList());
            Redis.key.del(key);
            if (!collect.isEmpty()) {
                Redis.list.pushList(key, collect);
            }
        }
    }
}
